Raycastのスクリプト実行の引数で濁点・半濁点が分離してしまう問題を解決する
Raycastを愛用しています! RaycastはMac専用のコマンドランチャーアプリです。 Alfredとほぼ同じことができると考えて良いかと思います。
Raycastの非常に気に入っている機能として、 シェルスクリプトなどをコマンドランチャーから簡単に実行することができる点があります。 やり方はこちらを参照してください。
この機能は省略可能な引数を受け取ることもできるので、 かなり利便性の高いスクリプトをホットキーで簡単に実行することができます。 控えめに言って最高です。
例えば私は自作のtodo管理アプリを使っているのですが、 タスク追加のAPIを実装して、 それを叩くようなスクリプトを叩くことでタスクを追加しています。 こんな感じです。 ちなみに与えられる引数の数は3つまでに制限されています。1
タスク追加は思いついた瞬間にできるだけ少ない手数で登録できることが重要なので、 todo管理アプリをアクティブにしてる暇なんてないのです。 そんなことしてる間にどんなタスクを登録すべきなのか忘れてしまいます。
問題発生
さてしばらくこの方法を使っていると、 todoとして登録している文字列の一部が検索で引っかからないことに気づきました。 具体的には、濁点・半濁点(パ行)などが引っかからないようでした。
調べてみると、 Raycastのスクリプト実行を通して入力されたタスク名で発生しているようでした。 そしてさらに調べると、その理由は例えば「パ」という文字が 「ハ」と「°」に分解されているというのが理由でした。2
これはシェルスクリプトに限らず、 Pythonを起動するような形式だとしても、 引数として渡された文字列で同様に発生している事象に見えました。
一方Raycastのスクリプト実行を経由しないでタスク登録した場合や、 Vim上で普通に日本語入力した場合は「パ」一文字になっているようでした。
問題の解決方法
なんでこんなことが起きているのかは気になりますが、 まずはこの問題を解決したいです。
そんな時は手っ取り早くChatGPTなどに聞いてしまうに限りますね。 実際にこんな感じに聞いてみました。
「パ」という文字が
e38391
ではなくe3838fe3829a
になってしまうことがあります。後者を前者に変換するにはどうしたらいいですか?
すると
echo "テキスト内にあるパとポを含むテキスト" | iconv -f utf-8 -t utf-8-mac | iconv -f utf-8-mac -t utf-8
こんなコマンドで変換できることを教えてくれました。 実際にシェルスクリプトに組み込むとこんな感じになります。
#!/bin/bash # Required parameters: # @raycast.schemaVersion 1 # @raycast.title task # @raycast.mode silent # Optional parameters: # @raycast.icon 🤖 # @raycast.argument1 {"type": "text", "placeholder": "task"} task="$(iconv -f utf-8 -t utf-8-mac | iconv -f utf-8-mac -t utf-8 <<< $1)"
これでタスク登録を試してみるとバッチリ「パ」一文字の形で登録されており、 検索もきちんと引っかかるようになりました!
めでたしめでたし。
変換コマンドは何をやっているのか
めでたいことついでに、少しだけ変換コマンドについて調べてみました。 ただ文字コード周りは難しいのであまり深追いはしていません...。
iconv
コマンドはmacOSであれば初めからインストールされているコマンドで、
文字コードの変換をしてくれるようです。
-f
はfrom、-t
はtoなので、
上記コマンドはある文字コードから文字コードへ変換して、
さらにそれをもう一度元の文字コードに戻しているようです。
utf-8-mac
はmacOSにおけるUnicode正規化を考慮した形式のようです。
(ここは用語の使い方として合っているのか定かではないです)
端的に使うとこんな感じです。
# utf-8-macに変換すると6バイト $ echo "パ" | iconv -f utf-8 -t utf-8-mac | xxd 00000000: e383 8fe3 829a 0a ....... # utf-8に変換すると3バイト $ echo "パ" | iconv -f utf-8-mac -t utf-8 | xxd 00000000: e383 910a ....
xxd
はバイナリを16進数で表示させるコマンドで、0a
は改行コードLF
のことです。
Unicode正規化
Unicode正規化は
「パ」と「ハ」+「°」が違うバイナリ列だから検索で引っかからないのつらすぎ...。 とりあえずどこかに揃えた方がよくない?
という発想のものだと理解して良さそうです。
もう少し踏み込むと、 「1(全角)」と「1(半角)」を同一と見做すかなどの 「同じ概念のものは一つのものに統一させるべきか否か」 という辺りの規定も含んでいるようです。
なおmacOSはファイル名にNFDの亜種(分解できるものは分解していくという方針) を採用しているらしく、 内部的には「ハ」+「°」形式でデータ保存されているらしいです。
まとめ
Raycastのスクリプトの引数に濁点・半濁点の文字を渡すと、
「ハ」と「°」に分解された文字としてのデータが渡されるようです。
macで通常文字を入力した場合は「パ」一文字に対応したデータが用いられているようなので
両者は検索で引っかからないなどの問題が発生してしまいます。
これを回避するため、iconv
を使って「パ」一文字の方に寄せるよう変換する方法をご紹介しました。
濁点・半濁点以外でこの問題が起きた場合にも 上記で示した変換方法で十全なのかはよくわかっていませんが、 少なくとも私が日本語環境で使っている上では、 この変換でそれ以上の問題は生じていない認識でいます。
Raycastのコマンドを定義すると ホットキーでいつでもどこからでも呼び出せるので 様々な場面で利用したくなりますね。 これで日本語でも問題なく使えそうなので色々活用していきたいです!
以上、誰かの参考になれば幸いです。